/************************ (C) COPYLEFT 2018 Merafour *************************

* File Name          : sin.c
* Author             : Merafour
* Last Modified Date : 01/10/2019
* Description        :  三角函数曲线.
********************************************************************************
* https://merafour.blog.163.com
* merafour@163.com
* https://github.com/merafour
******************************************************************************/
#include "Curve/Curve.h"

const float sin_table[361]={
0.000005, 0.017458, 0.034905, 0.052341, 0.069762, 0.087161, 0.104534, 0.121875, 0.139178, 0.156440, 0.173653, 0.190814, 0.207917, 0.224956, 0.241927,
0.258824, 0.275642, 0.292377, 0.309022, 0.325573, 0.342025, 0.358373, 0.374611, 0.390736, 0.406741, 0.422623, 0.438376, 0.453995, 0.469476, 0.484814,
0.500005, 0.515043, 0.529924, 0.544643, 0.559197, 0.573581, 0.587790, 0.601819, 0.615666, 0.629325, 0.642792, 0.656063, 0.669135, 0.682002, 0.694662,
0.707111, 0.719344, 0.731357, 0.743149, 0.754713, 0.766048, 0.777149, 0.788014, 0.798639, 0.809020, 0.819155, 0.829041, 0.838674, 0.848051, 0.857170,
0.866028, 0.874623, 0.882950, 0.891009, 0.898797, 0.906310, 0.913548, 0.920507, 0.927186, 0.933583, 0.939695, 0.945521, 0.951058, 0.956307, 0.961263,
0.965927, 0.970297, 0.974371, 0.978149, 0.981628, 0.984809, 0.987689, 0.990269, 0.992547, 0.994523, 0.996195, 0.997564, 0.998630, 0.999391, 0.999848,
1.000000, 0.999848, 0.999391, 0.998629, 0.997564, 0.996194, 0.994521, 0.992545, 0.990267, 0.987687, 0.984807, 0.981626, 0.978146, 0.974369, 0.970294,
0.965924, 0.961260, 0.956303, 0.951054, 0.945516, 0.939690, 0.933578, 0.927181, 0.920502, 0.913543, 0.906305, 0.898791, 0.891004, 0.882945, 0.874617,
0.866022, 0.857164, 0.848045, 0.838667, 0.829034, 0.819149, 0.809014, 0.798632, 0.788007, 0.777143, 0.766041, 0.754706, 0.743141, 0.731350, 0.719336,
0.707103, 0.694655, 0.681995, 0.669127, 0.656056, 0.642784, 0.629317, 0.615658, 0.601812, 0.587782, 0.573573, 0.559190, 0.544636, 0.529916, 0.515035,
0.499997, 0.484807, 0.469469, 0.453988, 0.438369, 0.422616, 0.406734, 0.390729, 0.374604, 0.358366, 0.342018, 0.325566, 0.309015, 0.292370, 0.275636,
0.258817, 0.241920, 0.224949, 0.207910, 0.190808, 0.173647, 0.156433, 0.139172, 0.121868, 0.104528, 0.087155, 0.069756, 0.052335, 0.034899, 0.017452,
-0.000000, -0.017453, -0.034900, -0.052336, -0.069756, -0.087156, -0.104528, -0.121869, -0.139173, -0.156434, -0.173648, -0.190808, -0.207911, -0.224950, -0.241921,
-0.258818, -0.275636, -0.292370, -0.309016, -0.325567, -0.342019, -0.358366, -0.374605, -0.390729, -0.406735, -0.422616, -0.438369, -0.453988, -0.469469, -0.484807,
-0.499998, -0.515036, -0.529917, -0.544637, -0.559190, -0.573574, -0.587783, -0.601812, -0.615659, -0.629318, -0.642785, -0.656056, -0.669128, -0.681996, -0.694655,
-0.707104, -0.719337, -0.731351, -0.743142, -0.754707, -0.766041, -0.777143, -0.788008, -0.798633, -0.809014, -0.819149, -0.829035, -0.838668, -0.848045, -0.857164,
-0.866023, -0.874617, -0.882945, -0.891004, -0.898791, -0.906305, -0.913543, -0.920502, -0.927181, -0.933578, -0.939690, -0.945516, -0.951054, -0.956303, -0.961260,
-0.965924, -0.970294, -0.974368, -0.978146, -0.981626, -0.984806, -0.987687, -0.990267, -0.992545, -0.994521, -0.996194, -0.997563, -0.998629, -0.999391, -0.999848,
-1.000000, -0.999848, -0.999391, -0.998630, -0.997565, -0.996195, -0.994523, -0.992547, -0.990269, -0.987690, -0.984809, -0.981629, -0.978150, -0.974372, -0.970298,
-0.965928, -0.961264, -0.956308, -0.951060, -0.945522, -0.939696, -0.933584, -0.927188, -0.920509, -0.913550, -0.906312, -0.898799, -0.891012, -0.882953, -0.874625,
-0.866031, -0.857173, -0.848054, -0.838677, -0.829044, -0.819159, -0.809024, -0.798643, -0.788018, -0.777154, -0.766052, -0.754718, -0.743153, -0.731362, -0.719349,
-0.707116, -0.694668, -0.682008, -0.669141, -0.656069, -0.642798, -0.629331, -0.615672, -0.601826, -0.587797, -0.573588, -0.559205, -0.544651, -0.529931, -0.515050,
-0.500013, -0.484822, -0.469485, -0.454004, -0.438385, -0.422632, -0.406750, -0.390745, -0.374621, -0.358382, -0.342035, -0.325583, -0.309032, -0.292387, -0.275653,
-0.258834, -0.241938, -0.224967, -0.207928, -0.190825, -0.173664, -0.156451, -0.139190, -0.121886, -0.104545, -0.087173, -0.069774, -0.052353, -0.034917, -0.017470,
-0.000017, };
const float cos_table[361]={
1.000000, 0.999848, 0.999391, 0.998629, 0.997564, 0.996194, 0.994521, 0.992545, 0.990267, 0.987688, 0.984807, 0.981626, 0.978146, 0.974369, 0.970294,
0.965924, 0.961260, 0.956303, 0.951055, 0.945517, 0.939691, 0.933579, 0.927182, 0.920503, 0.913543, 0.906306, 0.898792, 0.891004, 0.882945, 0.874617,
0.866023, 0.857165, 0.848045, 0.838668, 0.829035, 0.819149, 0.809014, 0.798632, 0.788007, 0.777143, 0.766041, 0.754706, 0.743141, 0.731350, 0.719336,
0.707103, 0.694654, 0.681994, 0.669126, 0.656055, 0.642783, 0.629316, 0.615657, 0.601811, 0.587781, 0.573572, 0.559188, 0.544634, 0.529914, 0.515033,
0.499995, 0.484805, 0.469466, 0.453985, 0.438366, 0.422613, 0.406731, 0.390726, 0.374601, 0.358362, 0.342015, 0.325563, 0.309011, 0.292366, 0.275632,
0.258813, 0.241916, 0.224945, 0.207906, 0.190803, 0.173642, 0.156428, 0.139167, 0.121863, 0.104522, 0.087150, 0.069750, 0.052330, 0.034893, 0.017446,
-0.000006, -0.017459, -0.034906, -0.052342, -0.069763, -0.087162, -0.104535, -0.121876, -0.139180, -0.156441, -0.173655, -0.190815, -0.207918, -0.224958, -0.241928,
-0.258825, -0.275644, -0.292378, -0.309023, -0.325575, -0.342027, -0.358374, -0.374613, -0.390737, -0.406743, -0.422624, -0.438377, -0.453996, -0.469477, -0.484815,
-0.500005, -0.515043, -0.529924, -0.544644, -0.559198, -0.573581, -0.587790, -0.601819, -0.615666, -0.629325, -0.642792, -0.656063, -0.669134, -0.682002, -0.694662,
-0.707110, -0.719343, -0.731357, -0.743148, -0.754712, -0.766047, -0.777149, -0.788013, -0.798638, -0.809019, -0.819154, -0.829040, -0.838673, -0.848050, -0.857169,
-0.866027, -0.874621, -0.882949, -0.891008, -0.898795, -0.906309, -0.913547, -0.920506, -0.927185, -0.933581, -0.939693, -0.945519, -0.951057, -0.956305, -0.961262,
-0.965926, -0.970296, -0.974370, -0.978148, -0.981627, -0.984808, -0.987689, -0.990268, -0.992546, -0.994522, -0.996195, -0.997564, -0.998630, -0.999391, -0.999848,
-1.000000, -0.999848, -0.999391, -0.998630, -0.997564, -0.996195, -0.994522, -0.992546, -0.990268, -0.987688, -0.984808, -0.981627, -0.978148, -0.974370, -0.970296,
-0.965926, -0.961262, -0.956305, -0.951057, -0.945519, -0.939693, -0.933581, -0.927185, -0.920506, -0.913546, -0.906309, -0.898795, -0.891008, -0.882949, -0.874621,
-0.866027, -0.857169, -0.848050, -0.838672, -0.829039, -0.819154, -0.809019, -0.798638, -0.788013, -0.777148, -0.766047, -0.754712, -0.743147, -0.731356, -0.719343,
-0.707110, -0.694661, -0.682002, -0.669134, -0.656062, -0.642791, -0.629324, -0.615665, -0.601819, -0.587789, -0.573581, -0.559197, -0.544643, -0.529924, -0.515043,
-0.500005, -0.484815, -0.469477, -0.453996, -0.438377, -0.422624, -0.406742, -0.390737, -0.374613, -0.358374, -0.342026, -0.325574, -0.309023, -0.292378, -0.275644,
-0.258826, -0.241929, -0.224958, -0.207919, -0.190816, -0.173656, -0.156442, -0.139181, -0.121877, -0.104536, -0.087164, -0.069765, -0.052344, -0.034908, -0.017461,
-0.000009, 0.017444, 0.034891, 0.052327, 0.069748, 0.087147, 0.104519, 0.121860, 0.139164, 0.156425, 0.173639, 0.190800, 0.207902, 0.224941, 0.241912,
0.258809, 0.275628, 0.292362, 0.309007, 0.325558, 0.342010, 0.358358, 0.374597, 0.390721, 0.406727, 0.422608, 0.438361, 0.453980, 0.469462, 0.484800,
0.499990, 0.515028, 0.529909, 0.544629, 0.559183, 0.573567, 0.587775, 0.601805, 0.615652, 0.629311, 0.642778, 0.656049, 0.669121, 0.681989, 0.694649,
0.707098, 0.719331, 0.731345, 0.743136, 0.754701, 0.766036, 0.777137, 0.788002, 0.798627, 0.809009, 0.819144, 0.829030, 0.838663, 0.848041, 0.857160,
0.866018, 0.874613, 0.882941, 0.891000, 0.898787, 0.906301, 0.913539, 0.920499, 0.927178, 0.933575, 0.939687, 0.945513, 0.951052, 0.956300, 0.961257,
0.965922, 0.970292, 0.974366, 0.978144, 0.981624, 0.984805, 0.987686, 0.990266, 0.992544, 0.994520, 0.996193, 0.997563, 0.998629, 0.999390, 0.999847,
1.000000, };

const uint8_t sin_rgb_blend[361]={
127, 129, 131, 133, 135, 138, 140, 142, 144, 146, 149, 151, 153, 155, 157, 
159, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 
190, 192, 194, 196, 198, 199, 201, 203, 205, 206, 208, 210, 211, 213, 215, 
216, 218, 219, 221, 222, 224, 225, 227, 228, 229, 231, 232, 233, 234, 235, 
236, 238, 239, 240, 241, 242, 243, 243, 244, 245, 246, 247, 247, 248, 249, 
249, 250, 250, 251, 251, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 
254, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 251, 251, 250, 250, 
249, 249, 248, 247, 247, 246, 245, 244, 243, 243, 242, 241, 240, 239, 238, 
236, 235, 234, 233, 232, 231, 229, 228, 227, 225, 224, 222, 221, 219, 218, 
216, 215, 213, 211, 210, 208, 206, 205, 203, 201, 199, 198, 196, 194, 192, 
190, 188, 186, 184, 182, 180, 178, 176, 174, 172, 170, 168, 166, 164, 162, 
159, 157, 155, 153, 151, 149, 146, 144, 142, 140, 138, 135, 133, 131, 129, 
126, 124, 122, 120, 118, 115, 113, 111, 109, 107, 104, 102, 100,  98,  96, 
 94,  91,  89,  87,  85,  83,  81,  79,  77,  75,  73,  71,  69,  67,  65, 
 63,  61,  59,  57,  55,  54,  52,  50,  48,  47,  45,  43,  42,  40,  38, 
 37,  35,  34,  32,  31,  29,  28,  26,  25,  24,  22,  21,  20,  19,  18, 
 17,  15,  14,  13,  12,  11,  10,  10,   9,   8,   7,   6,   6,   5,   4, 
  4,   3,   3,   2,   2,   1,   1,   1,   0,   0,   0,   0,   0,   0,   0, 
  0,   0,   0,   0,   0,   0,   0,   0,   1,   1,   1,   2,   2,   3,   3, 
  4,   4,   5,   6,   6,   7,   8,   9,  10,  10,  11,  12,  13,  14,  15, 
 17,  18,  19,  20,  21,  22,  24,  25,  26,  28,  29,  31,  32,  34,  35, 
 37,  38,  40,  42,  43,  45,  47,  48,  50,  52,  54,  55,  57,  59,  61, 
 63,  65,  67,  69,  71,  73,  75,  77,  79,  81,  83,  85,  87,  89,  91, 
 94,  96,  98, 100, 102, 104, 107, 109, 111, 113, 115, 118, 120, 122, 124, 
126, };
const uint8_t cos_rgb_blend[361]={
254, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 251, 251, 250, 250, 
249, 249, 248, 247, 247, 246, 245, 244, 243, 243, 242, 241, 240, 239, 238, 
236, 235, 234, 233, 232, 231, 229, 228, 227, 225, 224, 222, 221, 219, 218, 
216, 215, 213, 211, 210, 208, 206, 205, 203, 201, 199, 198, 196, 194, 192, 
190, 188, 186, 184, 182, 180, 178, 176, 174, 172, 170, 168, 166, 164, 162, 
159, 157, 155, 153, 151, 149, 146, 144, 142, 140, 138, 135, 133, 131, 129, 
126, 124, 122, 120, 118, 115, 113, 111, 109, 107, 104, 102, 100,  98,  96, 
 94,  91,  89,  87,  85,  83,  81,  79,  77,  75,  73,  71,  69,  67,  65, 
 63,  61,  59,  57,  55,  54,  52,  50,  48,  47,  45,  43,  42,  40,  38, 
 37,  35,  34,  32,  31,  29,  28,  26,  25,  24,  22,  21,  20,  19,  18, 
 17,  15,  14,  13,  12,  11,  10,  10,   9,   8,   7,   6,   6,   5,   4, 
  4,   3,   3,   2,   2,   1,   1,   1,   0,   0,   0,   0,   0,   0,   0, 
  0,   0,   0,   0,   0,   0,   0,   0,   1,   1,   1,   2,   2,   3,   3, 
  4,   4,   5,   6,   6,   7,   8,   9,  10,  10,  11,  12,  13,  14,  15, 
 17,  18,  19,  20,  21,  22,  24,  25,  26,  28,  29,  31,  32,  34,  35, 
 37,  38,  40,  42,  43,  45,  47,  48,  50,  52,  54,  55,  57,  59,  61, 
 63,  65,  67,  69,  71,  73,  75,  77,  79,  81,  83,  85,  87,  89,  91, 
 94,  96,  98, 100, 102, 104, 107, 109, 111, 113, 115, 118, 120, 122, 124, 
126, 129, 131, 133, 135, 138, 140, 142, 144, 146, 149, 151, 153, 155, 157, 
159, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 
190, 192, 194, 196, 198, 199, 201, 203, 205, 206, 208, 210, 211, 213, 215, 
216, 218, 219, 221, 222, 224, 225, 227, 228, 229, 231, 232, 233, 234, 235, 
236, 238, 239, 240, 241, 242, 243, 243, 244, 245, 246, 247, 247, 248, 249, 
249, 250, 250, 251, 251, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 
254, };

// RGB以120°相位差混色
uint32_t angle_rgb(uint16_t const angle)
{
	uint32_t color;
	//uint16_t angle_rgb[3];
	uint16_t r,g,b;
	uint16_t Angle = angle;
	uint16_t Angle120;
	uint16_t Angle240;
	//angle_rgb[0] = angle;
	//angle_rgb[1] = angle+120;
	//angle_rgb[2] = angle+240;
	//for(int i=0; i<3; i++) if(angle_rgb[i]>=360) angle_rgb[i] = angle_rgb[i] - 360;
	// 不能超过 360°
	for(int i=0; i<100; i++) 
	{
		if(Angle>=360) Angle = Angle - 360;
		else break;
	}
	Angle120 = Angle+120;
	Angle240 = Angle+240;
	if(Angle120>=360) Angle120 = Angle120 - 360;
	if(Angle240>=360) Angle240 = Angle240 - 360;
#if 0
	g = (uint32_t)(127*sin_table[angle_rgb[0]]+127);
	r = (uint32_t)(127*sin_table[angle_rgb[1]]+127);
	b = (uint32_t)(127*sin_table[angle_rgb[2]]+127);
#else // 节约算力
	g = sin_rgb_blend[Angle];
	r = sin_rgb_blend[Angle120];
	b = sin_rgb_blend[Angle240];
#endif
	color = 0xFF000000 | (r<<16) | (g<<8) | b;
	return color;
}
uint32_t angle_rg(uint16_t const angle)
{
	uint32_t color;
	uint16_t Angle[2];
	uint16_t r,g;
	
	Angle[0] = angle;
	Angle[1] = angle+180;
	for(int i=0; i<2; i++) if(Angle[i]>=360) Angle[i] = Angle[i] - 360;
	r = sin_rgb_blend[Angle[0]];
	g = sin_rgb_blend[Angle[1]];
	color = 0xFF000000 | (r<<16) | (g<<8);
	return color;
}
uint32_t angle_gb(uint16_t const angle)
{
	uint32_t color;
	uint16_t Angle[2];
	uint16_t g,b;
	
	Angle[0] = angle;
	Angle[1] = angle+180;
	for(int i=0; i<2; i++) if(Angle[i]>=360) Angle[i] = Angle[i] - 360;
	g = sin_rgb_blend[Angle[0]];
	b = sin_rgb_blend[Angle[1]];
	color = 0xFF000000 | (g<<8) | b;
	return color;
}
uint32_t angle_br(uint16_t const angle)
{
	uint32_t color;
	uint16_t Angle[2];
	uint16_t b,r;
	
	Angle[0] = angle;
	Angle[1] = angle+180;
	for(int i=0; i<2; i++) if(Angle[i]>=360) Angle[i] = Angle[i] - 360;
	b = sin_rgb_blend[Angle[0]];
	r = sin_rgb_blend[Angle[1]];
	color = 0xFF000000 | (r<<16) | b;
	return color;
}
// RGB以180°两两混色,rg[0-360], gb[360-720], br[720-1080]
uint32_t angle_rg_gb_br(uint16_t const angle)
{
	uint32_t color;
	uint16_t Angle, AnglePi;
	uint16_t red, green, blue;
	
	Angle = angle;         // 相位角
	// 不能超过 360°
	for(int i=0; i<100; i++) 
	{
		if(Angle>=360) Angle = Angle - 360;
		else break;
	}
	AnglePi = Angle+180;   // 前移 180°
	//qDebug("[%s--%d] angle[%4d, %3d, %3d] cos[%3d, %3d]\r\n", __func__, __LINE__, angle, Angle, AnglePi, cos_rgb_blend[Angle], cos_rgb_blend[AnglePi]);
	// 不能超过 360°
	if(AnglePi>=360) AnglePi = AnglePi - 360;
	/*for(int k=0; k<4; k++) for(int i=0; i<2; i++) 
	{
		if(Angle>=360)   Angle = Angle - 360;
		if(AnglePi>=360) AnglePi = AnglePi - 360;
	}*/
	if(angle<180)  // RG
	{
		red   = cos_rgb_blend[Angle];
		green = cos_rgb_blend[AnglePi];
		blue  = 0;
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	if(angle<360)  // BG
	{
		red   = 0;
		green = cos_rgb_blend[AnglePi];
		blue  = cos_rgb_blend[Angle];
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	if(angle<540)  // BR
	{
		red   = cos_rgb_blend[AnglePi];
		green = 0;
		blue  = cos_rgb_blend[Angle];
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	if(angle<720)  // GR
	{
		red   = cos_rgb_blend[AnglePi];
		green = cos_rgb_blend[Angle];
		blue  = 0;
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	if(angle<900)  // GB
	{
		red   = 0;
		green = cos_rgb_blend[Angle];
		blue  = cos_rgb_blend[AnglePi];
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	if(angle<1080)  // RB
	{
		red   = cos_rgb_blend[Angle];
		green = 0;
		blue  = cos_rgb_blend[AnglePi];
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	return 0x00000000;
}
uint32_t angle_256(uint16_t const angle)
{
	uint32_t color;
	uint16_t Angle, AnglePi;
	uint16_t red, green, blue;
	
	Angle = angle;         // 相位角
	// 不能超过 0xFF°
	Angle &= 0xFF;
	
	AnglePi = 255-Angle;   // 前移 180°
	//qDebug("[%s--%d] angle[%4d, %3d, %3d] cos[%3d, %3d]\r\n", __func__, __LINE__, angle, Angle, AnglePi, cos_rgb_blend[Angle], cos_rgb_blend[AnglePi]);
	if(angle<256*1)  // RG
	{
		red   = 255-Angle;
		green = 255-AnglePi;
		blue  = 0;
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	if(angle<256*2)  // BG
	{
		red   = 0;
		green = AnglePi;
		blue  = Angle;
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	if(angle<256*3)  // BR
	{
		red   = 255-AnglePi;
		green = 0;
		blue  = 255-Angle;
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	if(angle<256*4)  // GR
	{
		red   = AnglePi;
		green = Angle;
		blue  = 0;
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	if(angle<256*5)  // GB
	{
		red   = 0;
		green = 255-Angle;
		blue  = 255-AnglePi;
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	if(angle<256*6)  // RB
	{
		red   = Angle;
		green = 0;
		blue  = AnglePi;
		color = 0xFF000000 | (red<<16) | (green<<8) | blue;
		return color;
	}
	return 0x00000000;
}
